package guda.house.biz.impl;

import guda.grape.autogen.common.page.BaseQuery;
import guda.grape.autogen.common.page.BizResult;
import guda.house.biz.BillWaterElecBiz;
import guda.house.biz.bo.ElecFeeBO;
import guda.house.biz.bo.WaterFeeBO;
import guda.house.biz.constants.CommonResultCode;
import guda.house.biz.enums.WaterElecTypeEnum;
import guda.house.biz.form.bill.BillWaterElecEditForm;
import guda.house.biz.form.bill.BillWaterElecForm;
import guda.house.biz.query.*;
import guda.house.biz.util.Transform;
import guda.house.biz.util.TransformHelper;
import guda.house.dal.dao.*;
import guda.house.dal.dataobject.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by well on 16/1/21.
 */
public class BillWaterElecBizImpl implements BillWaterElecBiz {

    private final static Logger logger = LoggerFactory.getLogger(BillWaterBizImpl.class);

    @Autowired
    private BillWaterDAO billWaterDAO;
    @Autowired
    private WaterFeeBO waterFeeBO;

    @Autowired
    private BillElecDAO billElecDAO;
    @Autowired
    private ElecFeeBO elecFeeBO;
    @Autowired
    private SuiteDAO suiteDAO;
    @Autowired
    private BuildingDAO buildingDAO;
    @Autowired
    private UnitDAO unitDAO;

    @Override
    public BizResult detail(long id,String type) {
        BizResult bizResult = new BizResult();
        try{
            if(WaterElecTypeEnum.elec.name().equals(type)){
                BillElecDO billElecDO = billElecDAO.getBillElecById(id);
                bizResult.data.put("billDO", billElecDO);
            }else {
                BillWaterDO billWaterDO = billWaterDAO.getBillWaterById(id);
                bizResult.data.put("billDO", billWaterDO);
            }
            bizResult.success = true;
        }catch(Exception e){
            logger.error("query BillWater error",e);
        }
        return bizResult;
    }

    @Override
    public BizResult list(WaterElecQuery waterElecQuery) {
        BizResult bizResult = new BizResult();
        List<Long> suiteByName = new ArrayList<Long>();
        List<Long> suiteByVillateId = new ArrayList<Long>();
        if(waterElecQuery.getSuiteName()!=null){
            suiteByName = suiteDAO.getBySuiteName(waterElecQuery.getSuiteName());
        }
        if(waterElecQuery.getVillageId()!=null){
            BuildingQuery buildingQuery = new BuildingQuery();
            buildingQuery.setPageSize(10000);
            buildingQuery.setVillageId(waterElecQuery.getVillageId());
            List<BuildingDO> buildingDOs = buildingDAO.selectForPage(buildingQuery);
            List<Long> buildingIdList= TransformHelper.transform(buildingDOs, new Transform<BuildingDO, Long>() {
                @Override
                public Long transform(BuildingDO object) {
                    return object.getBuildingId();
                }
            });

            UnitQuery unitQuery = new UnitQuery();
            unitQuery.setPageSize(10000);
            unitQuery.setBuildingIdList(buildingIdList);
            List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
            List<Long> unitIdList = TransformHelper.transform(unitDOs, new Transform<UnitDO, Long>() {
                @Override
                public Long transform(UnitDO object) {
                    return object.getUnitId();
                }
            });

            SuiteQuery suiteQuery = new SuiteQuery();
            suiteQuery.setPageSize(10000);
            suiteQuery.setUnitIdList(unitIdList);
            List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
            suiteByVillateId= TransformHelper.transform(suiteDOs, new Transform<SuiteDO, Long>() {
                @Override
                public Long transform(SuiteDO object) {
                    return object.getSuiteId();
                }
            });
        }
        if(suiteByVillateId.size()>0){
            Iterator<Long> iterator = suiteByVillateId.iterator();
            while(iterator.hasNext()){
                Long id = iterator.next();
                if(!suiteByName.contains(id)){
                    iterator.remove();
                }
            }
        }else{
            suiteByVillateId.addAll(suiteByName);
        }
        if(WaterElecTypeEnum.elec.name().equals(waterElecQuery.getType())){
            BillElecQuery billElecQuery = new BillElecQuery();
            billElecQuery.setSuiteIdList(suiteByVillateId);
            billElecQuery.setPageSize(waterElecQuery.getPageSize());
            billElecQuery.setPageNo(waterElecQuery.getPageNo());
            List<BillElecDO> billElecDOList = billElecDAO.selectForPage(billElecQuery);
            int i = billElecDAO.countForPage(billElecQuery);
            waterElecQuery.setTotalCount(i);
            bizResult.data.put("billList", billElecDOList);
        }else {
            BillWaterQuery billWaterQuery = new BillWaterQuery();
            billWaterQuery.setSuiteIdList(suiteByVillateId);
            billWaterQuery.setPageSize(waterElecQuery.getPageSize());
            billWaterQuery.setPageNo(waterElecQuery.getPageNo());
            List<BillWaterDO> billWaterDOList = billWaterDAO.selectForPage(billWaterQuery);
            int i = billWaterDAO.countForPage(billWaterQuery);
            waterElecQuery.setTotalCount(i);
            bizResult.data.put("billList", billWaterDOList);
        }
        bizResult.success = true;

        return bizResult;
    }

    @Override
    public BizResult delete(long id,String type) {
        BizResult bizResult = new BizResult();
        if(WaterElecTypeEnum.elec.name().equals(type)){
            billElecDAO.delBillElecById(id);
            bizResult.success = true;
        }else if(WaterElecTypeEnum.water.name().equals(type)){
            billWaterDAO.delBillWaterById(id);
            bizResult.success = true;
        }
        return bizResult;
    }

    @Override
    public BizResult create(BillWaterElecForm billWaterElecForm) {
        BizResult bizResult = new BizResult();
        try {
            if(WaterElecTypeEnum.elec.name().equals(billWaterElecForm.getType())){
                BillElecDO billElecDO = new BillElecDO();
                billElecDO.setSuiteId(billWaterElecForm.getSuiteId());
                billElecDO.setRecordCurrent(billWaterElecForm.getRecordCurrent());
                billElecDO.setRecordMonth(billWaterElecForm.getRecordMonth());
                billElecDO.setRecordYear(billWaterElecForm.getRecordYear());
                billElecDO.setRecordLast(billWaterElecForm.getRecordLast());
                billElecDO.setRecordCurrent(billWaterElecForm.getRecordCurrent());
                billElecDO.setResetZero(billWaterElecForm.getResetZero());
                if (StringUtils.hasText(billWaterElecForm.getGmtRecord())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtRecord());
                        billElecDO.setGmtRecord(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (StringUtils.hasText(billWaterElecForm.getGmtStart())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtStart());
                        billElecDO.setGmtStart(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (StringUtils.hasText(billWaterElecForm.getGmtEnd())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtEnd());
                        billElecDO.setGmtEnd(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                billElecDO.setRecordTotal(billWaterElecForm.getRecordCurrent() - billWaterElecForm.getRecordLast());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(billElecDO.getGmtStart());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;

                //判断是否已经录入该月份的账单
                List<BillWaterDO> bill = billWaterDAO.getBill(billWaterElecForm.getSuiteId(), year, month);
                if (bill.size() > 0) {
                    bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                    return bizResult;
                }

                billElecDO.setRecordYear(year);
                billElecDO.setRecordMonth(month);
                billElecDO.setGmtRecord(new Date());
                billElecDO.setIsPayed(0);

                long payTotal = elecFeeBO.countElecFee(billWaterElecForm.getVillageId(),billWaterElecForm.getSuiteId(), billElecDO.getRecordTotal());
                billElecDO.setPayTotal(payTotal);

                long id = billElecDAO.insert(billElecDO);
                bizResult.data.put("id", id);
            }else if(WaterElecTypeEnum.water.name().equals(billWaterElecForm.getType())) {
                BillWaterDO billWaterDO = new BillWaterDO();
                billWaterDO.setSuiteId(billWaterElecForm.getSuiteId());
                billWaterDO.setRecordCurrent(billWaterElecForm.getRecordCurrent());
                billWaterDO.setRecordMonth(billWaterElecForm.getRecordMonth());
                billWaterDO.setRecordYear(billWaterElecForm.getRecordYear());
                billWaterDO.setRecordLast(billWaterElecForm.getRecordLast());
                billWaterDO.setRecordCurrent(billWaterElecForm.getRecordCurrent());
                billWaterDO.setResetZero(billWaterElecForm.getResetZero());
                if (StringUtils.hasText(billWaterElecForm.getGmtRecord())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtRecord());
                        billWaterDO.setGmtRecord(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (StringUtils.hasText(billWaterElecForm.getGmtStart())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtStart());
                        billWaterDO.setGmtStart(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                if (StringUtils.hasText(billWaterElecForm.getGmtEnd())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date parse = simpleDateFormat.parse(billWaterElecForm.getGmtEnd());
                        billWaterDO.setGmtEnd(parse);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                billWaterDO.setRecordTotal(billWaterElecForm.getRecordCurrent() - billWaterElecForm.getRecordLast());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(billWaterDO.getGmtStart());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH) + 1;

                //判断是否已经录入该月份的账单
                List<BillWaterDO> bill = billWaterDAO.getBill(billWaterElecForm.getSuiteId(), year, month);
                if (bill.size() > 0) {
                    bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                    return bizResult;
                }

                billWaterDO.setRecordYear(year);
                billWaterDO.setRecordMonth(month);
                billWaterDO.setGmtRecord(new Date());
                billWaterDO.setIsPayed(0);

                long payTotal = waterFeeBO.countWaterFee(billWaterElecForm.getVillageId(),billWaterElecForm.getSuiteId(), billWaterDO.getRecordTotal());
                billWaterDO.setPayTotal(payTotal);

                long id = billWaterDAO.insert(billWaterDO);
                bizResult.data.put("id", id);
            }

            bizResult.success = true;
        } catch (Exception e) {
            logger.error("create BillWater error", e);
        }
        return bizResult;
    }

    @Override
    public BizResult update(BillWaterElecEditForm billWaterElecEditForm) {
        BizResult bizResult = new BizResult();
        try {
            if(WaterElecTypeEnum.elec.name().equals(billWaterElecEditForm.getType())){
                BillElecDO billElecDO = new BillElecDO();
                billElecDO.setBillId(billWaterElecEditForm.getBillId());
                billElecDO.setSuiteId(billWaterElecEditForm.getSuiteId());
                billElecDO.setRecordCurrent(billWaterElecEditForm.getRecordCurrent());
                billElecDO.setRecordMonth(billWaterElecEditForm.getRecordMonth());
                billElecDO.setRecordYear(billWaterElecEditForm.getRecordYear());
                billElecDO.setRecordLast(billWaterElecEditForm.getRecordLast());
                billElecDO.setRecordCurrent(billWaterElecEditForm.getRecordCurrent());
                billElecDO.setResetZero(billWaterElecEditForm.getResetZero());
                billElecDO.setRecordTotal(billWaterElecEditForm.getRecordCurrent() - billWaterElecEditForm.getRecordLast());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(billElecDO.getGmtStart());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH)+1;

                //判断是否已经录入该月份的账单
                List<BillWaterDO> bill = billWaterDAO.getBill(billWaterElecEditForm.getSuiteId(), year, month);
                if(bill.size()>1){
                    bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                    return bizResult;
                }else if(bill.size() == 1){
                    if(bill.get(0).getBillId().intValue()!= billWaterElecEditForm.getBillId().intValue()){
                        bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                        return bizResult;
                    }
                }


                billElecDO.setRecordYear(year);
                billElecDO.setRecordMonth(month);
                billElecDO.setGmtRecord(new Date());

                long payTotal = elecFeeBO.countElecFee(billWaterElecEditForm.getVillageId(),billWaterElecEditForm.getSuiteId(), billElecDO.getRecordTotal());
                billElecDO.setPayTotal(payTotal);

                billElecDAO.updateByIdSelective(billElecDO);
            }else if(WaterElecTypeEnum.water.name().equals(billWaterElecEditForm.getType())){
                BillWaterDO billWaterDO = new BillWaterDO();
                billWaterDO.setBillId(billWaterElecEditForm.getBillId());
                billWaterDO.setSuiteId(billWaterElecEditForm.getSuiteId());
                billWaterDO.setRecordCurrent(billWaterElecEditForm.getRecordCurrent());
                billWaterDO.setRecordMonth(billWaterElecEditForm.getRecordMonth());
                billWaterDO.setRecordYear(billWaterElecEditForm.getRecordYear());
                billWaterDO.setRecordLast(billWaterElecEditForm.getRecordLast());
                billWaterDO.setRecordCurrent(billWaterElecEditForm.getRecordCurrent());
                billWaterDO.setRecordTotal(billWaterElecEditForm.getRecordCurrent() - billWaterElecEditForm.getRecordLast());
                billWaterDO.setResetZero(billWaterElecEditForm.getResetZero());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(billWaterDO.getGmtStart());
                int year = calendar.get(Calendar.YEAR);
                int month = calendar.get(Calendar.MONTH)+1;

                //判断是否已经录入该月份的账单
                List<BillWaterDO> bill = billWaterDAO.getBill(billWaterElecEditForm.getSuiteId(), year, month);
                if(bill.size()>1){
                    bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                    return bizResult;
                }else if(bill.size() == 1){
                    if(bill.get(0).getBillId().intValue()!= billWaterElecEditForm.getBillId().intValue()){
                        bizResult.code = CommonResultCode.BILL_WATER_REPEAT;
                        return bizResult;
                    }
                }


                billWaterDO.setRecordYear(year);
                billWaterDO.setRecordMonth(month);
                billWaterDO.setGmtRecord(new Date());

                long payTotal = waterFeeBO.countWaterFee(billWaterElecEditForm.getVillageId(),billWaterElecEditForm.getSuiteId(), billWaterDO.getRecordTotal());
                billWaterDO.setPayTotal(payTotal);

                billWaterDAO.updateByIdSelective(billWaterDO);
            }
        }catch (Exception e){
            logger.error("create BillWater error", e);
        }
        bizResult.success=true;
        return bizResult;
    }

    @Override
    public BizResult queryForEdit(BillWaterElecEditForm billWaterElecEditForm) {
        BizResult bizResult = new BizResult();
        try{
            if(WaterElecTypeEnum.elec.name().equals(billWaterElecEditForm.getType())){
                BillElecDO billElecDO = billElecDAO.getBillElecById(billWaterElecEditForm.getBillId());
                billWaterElecEditForm.setBillId(billElecDO.getBillId());
                billWaterElecEditForm.setRecordCurrent(billElecDO.getRecordCurrent());
                billWaterElecEditForm.setIsPayed(billElecDO.getIsPayed());
                billWaterElecEditForm.setRecordLast(billElecDO.getRecordLast());
                billWaterElecEditForm.setRecordCurrent(billElecDO.getRecordCurrent());
                billWaterElecEditForm.setRecordYear(billElecDO.getRecordYear());
                billWaterElecEditForm.setRecordMonth(billElecDO.getRecordMonth());
                billWaterElecEditForm.setResetZero(billElecDO.getResetZero());
                if(billElecDO.getGmtEnd()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtEnd(simpleDateFormat.format(billElecDO.getGmtEnd()));
                }
                if(billElecDO.getGmtStart()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtStart(simpleDateFormat.format(billElecDO.getGmtStart()));
                }
                if(billElecDO.getGmtRecord()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtRecord(simpleDateFormat.format(billElecDO.getGmtRecord()));
                }
                SuiteDO suiteById = suiteDAO.getSuiteById(billElecDO.getSuiteId());
                UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                BuildingDO buildingDO = buildingDAO.getBuildingById(unitById.getBuildingId());
                billWaterElecEditForm.setVillageId(buildingDO.getVillageId());
                billWaterElecEditForm.setBuildingId(buildingDO.getBuildingId());
                billWaterElecEditForm.setUnitId(unitById.getUnitId());
                billWaterElecEditForm.setSuiteId(billElecDO.getSuiteId());
                BuildingQuery buildingQuery = new BuildingQuery();
                buildingQuery.setPageSize(10000);
                buildingQuery.setVillageId(buildingDO.getVillageId());
                List<BuildingDO> buildingDOs = buildingDAO.selectForPage(buildingQuery);
                bizResult.data.put("buildingList", buildingDOs);

                UnitQuery unitQuery = new UnitQuery();
                unitQuery.setPageSize(10000);
                unitQuery.setBuildingId(buildingDO.getBuildingId());
                List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
                bizResult.data.put("unitList", unitDOs);

                SuiteQuery suiteQuery = new SuiteQuery();
                suiteQuery.setPageSize(10000);
                suiteQuery.setUnitId(unitById.getUnitId());
                List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
                bizResult.data.put("suiteList", suiteDOs);

            }else {
                BillWaterDO billWaterDO = billWaterDAO.getBillWaterById(billWaterElecEditForm.getBillId());
                billWaterElecEditForm.setBillId(billWaterDO.getBillId());
                billWaterElecEditForm.setRecordCurrent(billWaterDO.getRecordCurrent());
                billWaterElecEditForm.setIsPayed(billWaterDO.getIsPayed());
                billWaterElecEditForm.setRecordLast(billWaterDO.getRecordLast());
                billWaterElecEditForm.setRecordCurrent(billWaterDO.getRecordCurrent());
                billWaterElecEditForm.setRecordYear(billWaterDO.getRecordYear());
                billWaterElecEditForm.setRecordMonth(billWaterDO.getRecordMonth());
                billWaterElecEditForm.setResetZero(billWaterDO.getResetZero());
                if(billWaterDO.getGmtEnd()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtEnd(simpleDateFormat.format(billWaterDO.getGmtEnd()));
                }
                if(billWaterDO.getGmtStart()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtStart(simpleDateFormat.format(billWaterDO.getGmtStart()));
                }
                if(billWaterDO.getGmtRecord()!=null) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    billWaterElecEditForm.setGmtRecord(simpleDateFormat.format(billWaterDO.getGmtRecord()));
                }
                SuiteDO suiteById = suiteDAO.getSuiteById(billWaterDO.getSuiteId());
                UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                BuildingDO buildingDO = buildingDAO.getBuildingById(unitById.getBuildingId());
                billWaterElecEditForm.setVillageId(buildingDO.getVillageId());
                billWaterElecEditForm.setBuildingId(buildingDO.getBuildingId());
                billWaterElecEditForm.setUnitId(unitById.getUnitId());
                billWaterElecEditForm.setSuiteId(billWaterDO.getSuiteId());
                BuildingQuery buildingQuery = new BuildingQuery();
                buildingQuery.setPageSize(10000);
                buildingQuery.setVillageId(buildingDO.getVillageId());
                List<BuildingDO> buildingDOs = buildingDAO.selectForPage(buildingQuery);
                bizResult.data.put("buildingList", buildingDOs);

                UnitQuery unitQuery = new UnitQuery();
                unitQuery.setPageSize(10000);
                unitQuery.setBuildingId(buildingDO.getBuildingId());
                List<UnitDO> unitDOs = unitDAO.selectForPage(unitQuery);
                bizResult.data.put("unitList", unitDOs);

                SuiteQuery suiteQuery = new SuiteQuery();
                suiteQuery.setPageSize(10000);
                suiteQuery.setUnitId(unitById.getUnitId());
                List<SuiteDO> suiteDOs = suiteDAO.selectForPage(suiteQuery);
                bizResult.data.put("suiteList", suiteDOs);
            }
            bizResult.success = true;
        }catch(Exception e){
            logger.error("query BillWater error",e);
        }
        return bizResult;
    }
}
